﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "GraphicsStyleTable.h"
#include "IUiView.h"
#include "ILine3d.h"
#include "FilePath.h"
#include "IElement.h"
#include "ICategory.h"
#include "IDocument.h"
#include "IModelView.h"
#include "IUiDocument.h"
#include "FileUtility.h"
#include "UniIdentity.h"
#include "JournalUtils.h"
#include "IFillPattern.h"
#include "ILineTypeNew.h"
#include "ILineTypeData.h"
#include "UiCommonDialog.h"
#include "IPublishConfig.h"
#include "IGraphicsStyle.h"
#include "GbmpFileSystem.h"
#include "IGenericElement.h"
#include "ICategoryLibrary.h"
#include "IFillPatternData.h"
#include "IGraphicsMaterial.h"
#include "IFaceHatchPattern.h"
#include "CommandParameters.h"
#include "IGraphicsStyleData.h"
#include "IJournalCommandData.h"
#include "IGraphicsMaterialData.h"
#include "IGraphicsStyleManager.h"
#include "IUiDocumentViewManager.h"
#include "IGraphicsMaterialManager.h"
#include "IElementBasicInformation.h"
#include "IGraphicsStyleDataOverrideItems.h"
#include "GcmpBuiltInCategoryUniIdentities.h"

#include "QLabel"
#include "QObject"
#include "QWidget"
#include <QPainter>
#include <QComboBox>
#include "QCheckBox"
#include "QTableView"
#include <qlineedit.h>
#include "QPushButton"
#include "QHeaderView"
#include <QColorDialog>
#include "QTableWidget"
#include "LineTypeDlg.h"
#include "QItemDelegate"
#include "GStyleViewerUtils.h"
#include "CustomizerGStyleManager.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

/// 本文件是界面实现的辅助类，仅包含非常少的GDMP API的演示内容

static const UInt16 MaxLineWidth = 40; 

using namespace gcmp;
using namespace ggp;

namespace
{
    // 用于合成UV标示值
    const int buttonOffset = 1000;
    int MakeIndex(int column, int row)
    {
        return row + buttonOffset * column;
    }

    std::tuple<int, int> GetIndex(int index)
    {
        int column = index / buttonOffset;
        int row = index % buttonOffset;
        return {column, row};
    }
}

namespace Sample
{
#pragma region 辅助类
    static QString STR(std::wstring str)
    {
        return QString::fromStdWString(str);
    }

    static QString STR(std::string str)
    {
        return QString::fromStdString(str);
    }
#pragma endregion

#pragma region cell显示读取数据函数
    void GraphicsStyleTable::MakeCellDisable(int row, int column)
    {
        QLabel *label = new QLabel("", this);
        // 设置样式表使 QLabel 看起来像是被禁用  
        label->setStyleSheet("color: gray; background-color: #cccccc;");
        // 将 QLabel 设置为单元格的小部件  
        m_table->setCellWidget(row, column, label);
    }

    bool GraphicsStyleTable::IsAvailable(int row)
    {
        // 改行显示样式是否有内容？
        return m_gOverrideDataList.at(row)->m_available;
    }

    // 如果该Cell的显示样式不可用，则该Cell灰显显示
    bool GraphicsStyleTable::UpdateAvailableStatus(int row, int column)
    {
        if (!IsAvailable(row))
        {
            MakeCellDisable(row, column);
            return false;
        }
        return true;
    }

    void GraphicsStyleTable::ShowOverrideCell(int row, int column, OverrideFunc overrideFunc)
    {
        // 该行显示样式是否可用
        if (!UpdateAvailableStatus(row, column))return;
        // 该Cell显示样式数据的设置是否可以设置
        if (!overrideFunc.m_canOverride)
        {
            return MakeCellDisable(row, column);
        }
        // 显示样式重载的checkbox
        gcmp::OwnerPtr<QCheckBox> opCkBox = NEW_AS_OWNER_PTR(QCheckBox);
        bool flag = overrideFunc.m_getOverrideFunc(row);
        opCkBox->setChecked(flag);
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opCkBox));
    }

    bool GraphicsStyleTable::GetOverrideCell(int row, int column)
    {
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        return toOverride;
    }

    void GraphicsStyleTable::ShowLineWidthCell(GetDoubleFunc func, SetDoubleFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        double lineWidth = func(row);
        QStringList widthList;

        int maxWidth = MaxLineWidth;
        for (int ii = 1; ii < maxWidth + 1; ++ii)
        {
            widthList << QString::number(ii, 10);
        }
        if (lineWidth > maxWidth)
        {
            //如果获得线宽超过系统自定义的线宽把用户定义的线宽加上
            widthList << QString::number(lineWidth, 'f', 2);
        }

        gcmp::OwnerPtr<QComboBox> opComBox = NEW_AS_OWNER_PTR(QComboBox);
        opComBox->addItems(widthList);
        {
            if (lineWidth <= maxWidth)
            {
                opComBox->setCurrentIndex((int)lineWidth - 1);
            }
            else
            {
                //设用户自定义的宽度
                opComBox->setCurrentIndex(maxWidth);
            }
        }
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opComBox));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetDoubleFunc>* pSetFuncHolder = new FunctionHolder<SetDoubleFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    void GraphicsStyleTable::SetLineWidthCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column-1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetDoubleFunc>* pSetFuncHolder = (FunctionHolder<SetDoubleFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);

        QComboBox *comBox = dynamic_cast<QComboBox*>(m_table->cellWidget(row, column));
        int widthIndex = comBox->currentIndex() + 1;
        if (widthIndex > 0)
        {
            QString lineWidth = comBox->currentText();
            double widthofLine = lineWidth.toDouble();
            pSetFuncHolder->m_function(row, widthofLine);
        }
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowColorCell(GetColorFunc func, SetColorFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        gcmp::OwnerPtr<QPushButton> opColorButton = NEW_AS_OWNER_PTR(QPushButton);
        const Color& color = func(row);
        int index = MakeIndex(column, row);
        //看是否数据是非重载
        {
            QColor qColor(color.R, color.G, color.B, color.A);
            //存到color map里.
            m_colorMap[UVIndex(index, 2)] = qColor;
            opColorButton->setStyleSheet(QString("background-color:%1").arg(qColor.name()));
        }
        m_opColorBtnGroup->addButton(opColorButton.get(), index);
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opColorButton));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetColorFunc>* pSetFuncHolder = new FunctionHolder<SetColorFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    void GraphicsStyleTable::SetColorCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column-1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetColorFunc>* pSetFuncHolder = (FunctionHolder<SetColorFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);

        int index = MakeIndex(column, row);
        if (m_colorMap.find(UVIndex(index, 2)) != m_colorMap.end())
        {
            int r, g, b, a;
            QColor qColor = m_colorMap[UVIndex(index, 2)];
            qColor.getRgb(&r, &g, &b, &a);
            Color color(r, g, b, a);

            pSetFuncHolder->m_function(row, color);
        }
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowLineTypeCell(GetTextFunc func, SetTextFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        gcmp::OwnerPtr<QPushButton> opLineTypeButton = NEW_AS_OWNER_PTR(QPushButton);
        opLineTypeButton->setText(QString::fromStdWString(func(row)));
        m_opLineTypeBtnGroup->addButton(opLineTypeButton.get(), MakeIndex(column, row));
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opLineTypeButton));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetTextFunc>* pSetFuncHolder = new FunctionHolder<SetTextFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    void GraphicsStyleTable::SetLineTypeCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column - 1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetTextFunc>* pSetFuncHolder = (FunctionHolder<SetTextFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);

        QAbstractButton* pButton = m_opLineTypeBtnGroup->button(MakeIndex(column, row));
        std::wstring lineTypeName = pButton->text().toStdWString();
        pSetFuncHolder->m_function(row, lineTypeName);
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowEnabledCell(GetBoolFunc func, SetBoolFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        bool enable = func(row);
        gcmp::OwnerPtr<QCheckBox> pCheckBox(NEW_AS_OWNER_PTR(QCheckBox));
        pCheckBox->setChecked(enable);
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(pCheckBox));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetBoolFunc>* pSetFuncHolder = new FunctionHolder<SetBoolFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    void GraphicsStyleTable::SetEnabledCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column - 1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetBoolFunc>* pSetFuncHolder = (FunctionHolder<SetBoolFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);

        QCheckBox *ckBxValue = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column));
        pSetFuncHolder->m_function(row, ckBxValue->isChecked());
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowHatchPatternCell(GetTextFunc func, SetTextFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        std::wstring pattern = func(row);
        QStringList widthList;

        int i = 0;
        int currentIndex = 0;
        for (auto itor : m_hatchPatternNames)
        {
            widthList << QString::fromStdWString(itor);
            if (itor == pattern)
            {
                currentIndex = i;
            }
            i++;
        }

        gcmp::OwnerPtr<QComboBox> opComBox = NEW_AS_OWNER_PTR(QComboBox);
        opComBox->addItems(widthList);
        {
            opComBox->setCurrentIndex(currentIndex);
        }
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opComBox));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetTextFunc>* pSetFuncHolder = new FunctionHolder<SetTextFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    //设置填充样式
    void GraphicsStyleTable::SetHatchPatternCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column - 1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetTextFunc>* pSetFuncHolder = (FunctionHolder<SetTextFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);
           
        QComboBox *comBox = dynamic_cast<QComboBox*>(m_table->cellWidget(row, column));
        int widthIndex = comBox->currentIndex() + 1;
        if (widthIndex > 0)
        {
            QString qPattern = comBox->currentText();
            std::wstring pattern = qPattern.toStdWString();
            pSetFuncHolder->m_function(row, pattern);
        }
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowRotateCell(GetDoubleFunc func, SetDoubleFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        gcmp::OwnerPtr<QLineEdit> opLineEdit = NEW_AS_OWNER_PTR(QLineEdit);
        QIntValidator* pInputValidator = NEW_AS_QT_CHILD(QIntValidator, this);
        pInputValidator->setRange(-360, 360);
        opLineEdit->setValidator(pInputValidator);
        int idx = static_cast<int>(MathUtils::RadiansToAngle(func(row)));
        opLineEdit->setText(QString::number(idx));
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opLineEdit));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetDoubleFunc>* pSetFuncHolder = new FunctionHolder<SetDoubleFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    void GraphicsStyleTable::SetRotateCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column - 1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetDoubleFunc>* pSetFuncHolder = (FunctionHolder<SetDoubleFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);

        bool bval = false;
        QLineEdit *lineEdit = dynamic_cast<QLineEdit*>(m_table->cellWidget(row, column));
        int angle = lineEdit->text().toInt(&bval);
        double radians = MathUtils::AngleToRadians(angle);
        pSetFuncHolder->m_function(row, radians);
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowScaleCell(GetDoubleFunc func, SetDoubleFunc setFunc, OverrideFunc overrideFunc, int row, int column)
    {
        ShowOverrideCell(row, column, overrideFunc);
        column++;
        if (!UpdateAvailableStatus(row, column))return;

        gcmp::OwnerPtr<QLineEdit> opLineEdit = NEW_AS_OWNER_PTR(QLineEdit);
        QDoubleValidator* pInputValidator = NEW_AS_QT_CHILD(QDoubleValidator, this);
        pInputValidator->setRange(0.0001, 100000000);
        pInputValidator->setDecimals(2);
        opLineEdit->setValidator(pInputValidator);
        double idx = func(row);
        opLineEdit->setText(QString::number(idx));
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opLineEdit));
        // 显示样式设置回m_gOverrideDataList的回调函数，绑定到控件上
        FunctionHolder<SetDoubleFunc>* pSetFuncHolder = new FunctionHolder<SetDoubleFunc>(setFunc, overrideFunc);
        QVariant qPointer = QVariant::fromValue((void *)pSetFuncHolder);
        m_setFuncDict[UVIndex(row, column)] = qPointer;
    }

    void GraphicsStyleTable::SetScaleCell(int row, int column)
    {
        if (!IsAvailable(row))return;
        // 从控件获得设置m_gOverrideDataList的回调函数类pSetFuncHolder，设置重载bool值和样式重载
        QCheckBox *ckBx = dynamic_cast<QCheckBox*>(m_table->cellWidget(row, column - 1));
        bool toOverride = (ckBx == nullptr) || ckBx->isChecked();
        QVariant qPointer = m_setFuncDict[UVIndex(row, column)];
        FunctionHolder<SetDoubleFunc>* pSetFuncHolder = (FunctionHolder<SetDoubleFunc>*)qPointer.value<void*>();  // 获取指针
        DBG_WARN_AND_RETURN_VOID_UNLESS(pSetFuncHolder, L"pSetFuncHolder 为空",L"GDMP",L"2024-03-30");
        pSetFuncHolder->m_overrideFunc.m_setOverrideFunc(row, toOverride);

        bool bval = false;
        QLineEdit *lineEdit = dynamic_cast<QLineEdit*>(m_table->cellWidget(row, column));
        double scale = lineEdit->text().toDouble(&bval);
        pSetFuncHolder->m_function(row, scale);
        delete pSetFuncHolder;
    }

    void GraphicsStyleTable::ShowTextCell(std::wstring text, int row, int column, bool isReadOnly)
    {
        if (!UpdateAvailableStatus(row, column))return;
        gcmp::OwnerPtr<QLineEdit> opLineEdit = NEW_AS_OWNER_PTR(QLineEdit);
        opLineEdit->setText(QString::fromStdWString(text));
        if (isReadOnly)
        {
            opLineEdit->setEnabled(false);
        }
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opLineEdit));
    }

    std::wstring GraphicsStyleTable::GetTextCell(int row, int column)
    {
        QLineEdit *lineEdit = dynamic_cast<QLineEdit*>(m_table->cellWidget(row, column));
        if (lineEdit)
        {
            return lineEdit->text().toStdWString();
        }
        return L"";
    }

    static std::wstring s_emptyCategory = L"没有类别";

    void GraphicsStyleTable::ShowCategoryCell(int row, int column, const ICategory* pCurrentCategory, bool isEnabled)
    {
        // 图形节点上样式的类别
        std::wstring currentCategory = L"";
        if (pCurrentCategory)
        {
            currentCategory = pCurrentCategory->GetDisplayName();
        }
        else
        {
            currentCategory = s_emptyCategory;
        }

        IDocument* pDoc = m_wpUIDoc->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc 为空",L"GDMP",L"2024-03-30");
        CustomizerGStyleManager* pGManger = CustomizerGStyleManager::Get(pDoc);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pGManger, L"pGManger为空",L"GDMP",L"2024-03-30");

        // 示例程序设计为只有CustomizerGStyleManager::GetGStyleCategories()中的类别可以直接设置到图形节点上
        auto cateMap = pGManger->GetGStyleCategories();
        QStringList widthList;
        widthList << QString::fromStdWString(s_emptyCategory);
        int i = 0;
        int currentIndex = -1;
        for (auto itor : cateMap)
        {
            std::wstring categoryName = itor.first;
            widthList << QString::fromStdWString(categoryName);
            if (categoryName == currentCategory)
            {
                currentIndex = i + 1;
            }
            i++;
        }

        if (currentIndex < 0)
        {
            if (currentCategory == s_emptyCategory)
            {
                currentIndex = 0;
            }
            else
            {
                widthList << QString::fromStdWString(currentCategory);
                currentIndex = widthList.size() - 1;
                // 示例程序设计为：只有图形节点上样式的类别在CustomizerGStyleManager::GetGStyleCategories()中时才可以修改
                isEnabled = false;
            }
        }

        gcmp::OwnerPtr<QComboBox> opComBox = NEW_AS_OWNER_PTR(QComboBox);
        opComBox->addItems(widthList);
        {
            opComBox->setCurrentIndex(currentIndex);
        }
        opComBox->setEnabled(isEnabled);
        m_table->setCellWidget(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opComBox));
    }

    //设置图元节点类别
    void GraphicsStyleTable::SetCategoryCell(int row, int column)
    {
        QComboBox *comBox = dynamic_cast<QComboBox*>(m_table->cellWidget(row, column));
        if (!comBox || !comBox->isEnabled())
        {
            return;
        }
        if (comBox->currentIndex() >= 0)
        {
            OwnerPtr<GraphicsOverrideData>& opGraphicsOverrideData = m_gOverrideDataList[row];
            DBG_WARN_AND_RETURN_VOID_UNLESS(opGraphicsOverrideData, L"opGraphicsOverrideData 为空",L"GDMP",L"2024-03-30");
            QString qCategoryName = comBox->currentText();
            std::wstring categoryName = qCategoryName.toStdWString();
            if (categoryName == s_emptyCategory)
            {
                opGraphicsOverrideData->m_gNodeCategory = nullptr;
                opGraphicsOverrideData->m_gStyleId = ElementId::InvalidID;
            }

            IDocument* pDoc = m_wpUIDoc->GetDbDocument();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc 为空",L"GDMP",L"2024-03-30");
            CustomizerGStyleManager* pGManger = CustomizerGStyleManager::Get(pDoc);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pGManger, L"pGManger为空",L"GDMP",L"2024-03-30");
            auto cateMap = pGManger->GetGStyleCategories();
            auto& iter = cateMap.find(categoryName);
            if (iter != cateMap.end())
            {
                opGraphicsOverrideData->m_gNodeCategory = iter->second;
                IGraphicsStyleManager* pGStyleManager = pDoc->GetGraphicsStyleManager();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pGStyleManager, L"pGStyleManager为空",L"GDMP",L"2024-03-30");
                m_gOverrideDataList[row]->m_gStyleId = pGStyleManager->GetGraphicsStyleIdByCategoryUid(iter->second->GetUniIdentity());
            }
        }
    }
#pragma endregion

#pragma region 表格初始化
    // 表格中显示样式的行数
    const int GraphicsStyleTable::s_numStyleLines = 9;
    // 【投影和截面线样式】表格的列数
    const int GraphicsStyleTable::s_countLinePageColumns = 23;
    // 【投影和截面面样式】表格的列数
    const int GraphicsStyleTable::s_countFacePageColumns = 23;

    GraphicsStyleTable::GraphicsStyleTable(gcmp::IUiDocument* pUIDoc, gcmp::IUiView* currentView,
        QDialog* parent, TableType tableType, std::vector<gcmp::OwnerPtr<GraphicsOverrideData>>& gOverrideDataList)
        : m_parent(parent)
        , m_wpUIDoc(pUIDoc)
        , m_wpCurrentView(currentView)
        , m_tableType(tableType)
        , m_gOverrideDataList(gOverrideDataList)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_gOverrideDataList.size() == s_numStyleLines, L"m_gOverrideDataList个数错误",L"GDMP",L"2024-03-30");
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_wpUIDoc, L"m_wpUIDoc为空",L"GDMP",L"2024-03-30");
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_wpCurrentView, L"m_wpCurrentView为空",L"GDMP",L"2024-03-30");
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_parent, L"m_parent为空",L"GDMP",L"2024-03-30");

        m_opColorBtnGroup = NEW_AS_OWNER_PTR(QButtonGroup);
        m_opLineTypeBtnGroup = NEW_AS_OWNER_PTR(QButtonGroup);

        // 文档对象Tab页
        m_table = NEW_AS_QT_CHILD(QTableWidget, m_parent);
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_table, L"m_table为空",L"GDMP",L"2024-03-30");
        m_table->setObjectName(QStringLiteral("GraphicsStyleTable"));
        m_table->verticalHeader()->setHidden(true);
        m_table->horizontalHeader()->setStretchLastSection(true);
        QObject::connect(m_table, SIGNAL(cellClicked(int, int)), this, SLOT(OnClickColorCell(int, int)));
        QObject::connect(m_opColorBtnGroup.get(), SIGNAL(buttonClicked(int)), this, SLOT(OnClickColorCell(int)));
        QObject::connect(m_opLineTypeBtnGroup.get(), SIGNAL(buttonClicked(int)), this, SLOT(OnClickLineTypeCell(int)));

        ////////////////////////////////////////////////////////////////////////////////////
        if (m_tableType == TableType::ProjectionSectionLines)
        {
            initLines();
        }
        else if (m_tableType == TableType::ProjectionSectionFaces)
        {
            initFaces();
        }
        else
        {
            DBG_WARN(L"m_tableType超出预期",L"GDMP",L"2024-03-30");
        }
    }

    void GraphicsStyleTable::initLines()
    {
        // 获取样式类型
        // 设置样式表头
        m_table->setColumnCount(s_countLinePageColumns);
        m_table->setRowCount(s_numStyleLines);

        // 分别设置是否重载和重载项两列的宽度
        for (int i = 0; i < s_countLinePageColumns - 1; i++)
        {
            if (i % 2 == 0) {
                m_table->setColumnWidth(i, 80);
            }
            else {
                m_table->setColumnWidth(i, 35);
            }
        }
        // 设置第一列和最后两列的宽度
        m_table->setColumnWidth(0, 130);
        m_table->setColumnWidth(21, 110);
        m_table->setColumnWidth(22, 80);
        {
            QStringList header;
            header << STR(GBMP_TR(L"样式重载名称")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影线宽")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影线颜色"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影线型")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影线缩放"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面线宽")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面线颜色")) 
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面线型")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面线缩放"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"透明度")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影线Alpha"))
                << STR(GBMP_TR(L"节点样式名称")) << STR(GBMP_TR(L"节点样式类别"));
            m_table->setHorizontalHeaderLabels(header);
            int lineNum = -1;

            for (int i = 0; i < s_numStyleLines; i++)
            {
                m_table->model()->setHeaderData(++lineNum, Qt::Horizontal, header.at(i), Qt::AccessibleDescriptionRole);
            }
        }
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_wpUIDoc, L"m_wpUIDoc == nullptr",L"GDMP",L"2024-03-30");
        gcmp::IDocument* pDoc = m_wpUIDoc->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"doc 为空",L"GDMP",L"2024-03-30");

        // 类别级显示样式，没有是否可以重载的bool设置
        GetBoolFunc dummyGetFunc = [&](int row) { return false; };
        SetBoolFunc dummySetFunc = [&](int row, bool v) {};
        OverrideFunc dummyOverrideFunc(dummyGetFunc, dummySetFunc, false);

        // 是否可以重载的获得和设置回调函数
        OverrideFuncListList overrideFuncListList;
        {
            OverrideFuncList overrideDummyFuncList;
            for (int i = 0; i < s_countLinePageColumns; i++) { overrideDummyFuncList.push_back(dummyOverrideFunc); };

            OverrideFuncList overrideItemsFuncList = {
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsProjectionLineWidthOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideProjectionLineWidth(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsProjectionLineColorOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideProjectionLineColor(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsProjectionLineTypeNameOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideProjectionLineTypeName(v); }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsSectionLineWidthOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideSectionLineWidth(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsSectionLineColorOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideSectionLineColor(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsSectionLineTypeNameOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideSectionLineTypeName(v); }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsTransparencyOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideTransparency(v); }),
                dummyOverrideFunc
            };

            OverrideFuncList overrideValidateFuncList = {
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionLineWidthValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionLineWidthValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionLineColorValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionLineColorValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionLineTypeNameValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionLineTypeNameValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionLineTypeScaleValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionLineTypeScaleValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionLineWidthValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionLineWidthValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionLineColorValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionLineColorValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionLineTypeNameValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionLineTypeNameValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionLineTypeScaleValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionLineTypeScaleValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsTransparencyValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetTransparencyValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsEnableProjectionLineColorAlphaValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetEnableProjectionLineColorAlphaValidity(v); }),
            };

            overrideFuncListList.push_back(overrideDummyFuncList);
            overrideFuncListList.push_back(overrideItemsFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
        }
        // 图形节点所在行
        static int s_rowNumOfGNodeSetDirectly = 8;
        for (int row = 0; row < s_numStyleLines; row++)
        {
            int column = 0;
            // 样式名称
            {
                gcmp::OwnerPtr<QTableWidgetItem> opItem = NEW_AS_OWNER_PTR(QTableWidgetItem, QString::fromStdWString(m_rowNames[row]));
                opItem->setFlags(Qt::ItemIsEnabled);
                m_table->setItem(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opItem));
            }

            OwnerPtr<IGraphicsStyleData>& opDocGStyleData = m_gOverrideDataList[row]->m_opGStyleData;
            OverrideFuncList overrideFuncList = overrideFuncListList[row];
            
            // 如果图形节点上的样式是类别样式，则不能修改是否重载，否则该类别的图元可能显示错误。
            IGraphicsStyle* pGStyle = quick_cast<IGraphicsStyle>(pDoc->GetElement(m_gOverrideDataList[row]->m_gStyleId));
            if (pGStyle && pGStyle->GetTargetCategoryUid().IsValid())
            {
                for (auto& iter : overrideFuncList)
                {
                    // 类别样式各项不能修改是否重载
                    iter.m_canOverride = false;
                }
            }

            //添加投影线宽
            column++;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionLineWidth(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionLineWidth(width); };
                ShowLineWidthCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            //添加投影颜色
            column += 2;
            {
                GetColorFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionLineColor(); };
                SetColorFunc setFunc = [&](int row, gcmp::Color color) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionLineColor(color); };
                ShowColorCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            //投影线型
            column += 2;
            {
                GetTextFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionLineTypeName(); };
                SetTextFunc setFunc = [&](int row, std::wstring txt) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionLineTypeName(txt); };
                ShowLineTypeCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            //投影线型缩放
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionLineTypeScale(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionLineTypeScale(width); };
                ShowScaleCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            // 截面线宽
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionLineWidth(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionLineWidth(width); };
                ShowLineWidthCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            //添加截面线颜色
            column += 2;
            {
                GetColorFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionLineColor(); };
                SetColorFunc setFunc = [&](int row, gcmp::Color color) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionLineColor(color); };
                ShowColorCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            // 截面线型
            column += 2;
            {
                GetTextFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionLineTypeName(); };
                SetTextFunc setFunc = [&](int row, std::wstring txt) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionLineTypeName(txt); };
                ShowLineTypeCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            //截面线型缩放
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionLineTypeScale(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionLineTypeScale(width); };
                ShowScaleCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            // 透明度
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetTransparency(); };
                SetDoubleFunc setFunc = [&](int row, double trans) { m_gOverrideDataList[row]->m_opGStyleData->SetTransparency(trans); };
                ShowScaleCell(func, setFunc, overrideFuncList[column/2], row, column);
            }

            // 投影线alpha是否有效
            column += 2;
            {
                GetBoolFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->IsProjectionLineColorAlphaEnabled(); };
                SetBoolFunc setFunc = [&](int row, bool enabled) { m_gOverrideDataList[row]->m_opGStyleData->EnableProjectionLineColorAlpha(enabled); };
                ShowEnabledCell(func, setFunc, overrideFuncList[column/2], row, column);
            }
            // 图形节点重载的样式名称
            column +=2;
            {
                bool isGNodeRow = (row == s_rowNumOfGNodeSetDirectly); // 仅直接设置图形节点样式时，可以修改
                if (m_gOverrideDataList[row]->m_hasGNodeText || isGNodeRow)
                {
                    ShowTextCell(m_gOverrideDataList[row]->m_gNodeText, row, column, !isGNodeRow);
                }
                else
                {
                    MakeCellDisable(row, column);
                }
            }
            // 图形节点重载的样式类别名称
            column ++;
            {
                bool isGNodeRow = (row == s_rowNumOfGNodeSetDirectly);// 仅直接设置图形节点样式时，可以修改
                if (m_gOverrideDataList[row]->m_hasGNodeCategory || isGNodeRow)
                {
                    ShowCategoryCell(row, column, m_gOverrideDataList[row]->m_gNodeCategory, isGNodeRow);
                }
                else
                {
                    MakeCellDisable(row, column);
                }
            }
        }
    }

    void GraphicsStyleTable::initFaces()
    {
        // 设置样式表头
        m_table->setColumnCount(s_countFacePageColumns);
        m_table->setRowCount(s_numStyleLines);

        for (int i = 0; i < s_countFacePageColumns - 1; i++)
        {
            if (i % 2 == 0) {
                m_table->setColumnWidth(i, 85);
            }
            else {
                m_table->setColumnWidth(i, 35);
            }
        }
        m_table->setColumnWidth(0, 130);
        {
            QStringList header;
            header << STR(GBMP_TR(L"样式重载名称")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影填充颜色")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影填充样式"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影填充旋转")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影填充缩放"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"投影填充线宽"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面填充颜色")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面填充样式"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面填充旋转")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面填充缩放"))
                << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"表面颜色")) << STR(GBMP_TR(L"重载")) << STR(GBMP_TR(L"截面颜色"));
            m_table->setHorizontalHeaderLabels(header);
            int lineNum = -1;

            for (int i = 0; i < s_numStyleLines; i++)
            {
                m_table->model()->setHeaderData(++lineNum, Qt::Horizontal, header.at(i), Qt::AccessibleDescriptionRole);
            }
        }
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_wpUIDoc, L"m_wpUIDoc == nullptr",L"GDMP",L"2024-03-30");
        gcmp::IDocument* pDoc = m_wpUIDoc->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"doc 为空",L"GDMP",L"2024-03-30");

        // 对IGraphicsStyleData和IGraphicsStyleDataValiditySettings获取和设置的回调函数
        GetBoolFunc dummyGetFunc = [&](int row) { return false; };
        SetBoolFunc dummySetFunc = [&](int row, bool v) {};
        OverrideFunc dummyOverrideFunc(dummyGetFunc, dummySetFunc, false);

        OverrideFuncListList overrideFuncListList;
        {
            OverrideFuncList overrideDummyFuncList;
            for (int i = 0; i < s_countFacePageColumns; i++) { overrideDummyFuncList.push_back(dummyOverrideFunc); };

            GraphicsStyleTable::OverrideFuncList overrideValidateFuncList = {
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionFaceHatchColorValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionFaceHatchColorValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionFaceHatchPatternValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionFaceHatchPatternValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionFaceHatchRotationValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionFaceHatchRotationValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionFaceHatchScaleValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionFaceHatchScaleValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsProjectionFaceHatchLineWidthValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetProjectionFaceHatchLineWidthValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionFaceHatchColorValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionFaceColorValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionFaceHatchPatternValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionFaceHatchPatternValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionFaceHatchRotationValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionFaceHatchRotationValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionFaceHatchScaleValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionFaceHatchScaleValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsColorValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetColorValidity(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->IsSectionFaceColorValid(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataValiditySettings->SetSectionFaceColorValidity(v); }),
            };

            GraphicsStyleTable::OverrideFuncList overrideItemsFuncList = {
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsProjectionFaceHatchColorOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideProjectionFaceHatchColor(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsProjectionFaceHatchPatternOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideProjectionFaceHatchPattern(v); }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsSectionFaceHatchColorOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideSectionFaceHatchColor(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsSectionFaceHatchPatternOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideSectionFaceHatchPattern(v); }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return false; },
                [&](int row, bool v) { return; }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsColorOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideColor(v); }),
                OverrideFunc([&](int row) {return m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->IsSectionFaceColorOverridden(); },
                [&](int row, bool v) { m_gOverrideDataList[row]->m_opGStyleDataOverrideItems->OverrideSectionFaceColor(v); }),
            };
           
            overrideFuncListList.push_back(overrideDummyFuncList);
            overrideFuncListList.push_back(overrideItemsFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
            overrideFuncListList.push_back(overrideValidateFuncList);
        }

        GStyleViewerUtils::GetHatchPatternNames(pDoc, m_hatchPatternNames);

        for (int row = 0; row < s_numStyleLines; row++)
        {
            int column = 0;
            // 样式名称
            {
                gcmp::OwnerPtr<QTableWidgetItem> opItem = NEW_AS_OWNER_PTR(QTableWidgetItem, QString::fromStdWString(m_rowNames[row]));
                opItem->setFlags(Qt::ItemIsEnabled);
                m_table->setItem(row, column, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(opItem));
            }

            OwnerPtr<IGraphicsStyleData>& opDocGStyleData = m_gOverrideDataList[row]->m_opGStyleData;
            OverrideFuncList overrideFuncList = overrideFuncListList[row];

            // 如果图形节点上的样式是类别样式，则不能修改是否重载，否则该类别的图元可能显示错误。
            IGraphicsStyle* pGStyle = quick_cast<IGraphicsStyle>(pDoc->GetElement(m_gOverrideDataList[row]->m_gStyleId));
            if (pGStyle && pGStyle->GetTargetCategoryUid().IsValid())
            {
                for (auto& iter : overrideFuncList)
                {
                    // 类别样式各项不能修改是否重载
                    iter.m_canOverride = false;
                }
            }

            //投影填充颜色
            column++;
            {
                GetColorFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionFaceHatchColor(); };
                SetColorFunc setFunc = [&](int row, gcmp::Color color) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionFaceHatchColor(color); };
                ShowColorCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            //投影填充样式
            column += 2;
            {
                GetTextFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionFaceHatchPattern(); };
                SetTextFunc setFunc = [&](int row, std::wstring txt) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionFaceHatchPattern(txt); };
                ShowHatchPatternCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            //投影填充旋转
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionFaceHatchRotation(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionFaceHatchRotation(width); };
                ShowRotateCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            // 投影填充缩放
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionFaceHatchScale(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionFaceHatchScale(width); };
                ShowScaleCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            // 投影填充线宽
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetProjectionFaceHatchLineWidth(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetProjectionFaceHatchLineWidth(width); };
                ShowScaleCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            //截面填充颜色
            column += 2;
            {
                GetColorFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionFaceHatchColor(); };
                SetColorFunc setFunc = [&](int row, gcmp::Color color) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionFaceHatchColor(color); };
                ShowColorCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            //截面填充样式
            column += 2;
            {
                GetTextFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionFaceHatchPattern(); };
                SetTextFunc setFunc = [&](int row, std::wstring txt) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionFaceHatchPattern(txt); };
                ShowHatchPatternCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            //截面填充旋转
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionFaceHatchRotation(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionFaceHatchRotation(width); };
                ShowRotateCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            // 截面填充缩放
            column += 2;
            {
                GetDoubleFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionFaceHatchScale(); };
                SetDoubleFunc setFunc = [&](int row, double width) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionFaceHatchScale(width); };
                ShowScaleCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }

            // 表面颜色
            column += 2;
            {
                GetColorFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetColor(); };
                SetColorFunc setFunc = [&](int row, gcmp::Color color) { m_gOverrideDataList[row]->m_opGStyleData->SetColor(color); };
                ShowColorCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }
            // 截面颜色
            column += 2;
            {
                GetColorFunc func = [&](int row) { return m_gOverrideDataList[row]->m_opGStyleData->GetSectionFaceColor(); };
                SetColorFunc setFunc = [&](int row, gcmp::Color color) { m_gOverrideDataList[row]->m_opGStyleData->SetSectionFaceColor(color); };
                ShowColorCell(func, setFunc, overrideFuncList[column / 2], row, column);
            }
        }
    }
#pragma endregion

#pragma region UI事件
    void GraphicsStyleTable::OnClickColorCell(int bnt)
    {
        QPushButton *colorButton = dynamic_cast<QPushButton*>(m_opColorBtnGroup->button(bnt));
        int column, row;
        std::tie(column, row) = GetIndex(bnt);
        QColor qColor = m_colorMap[UVIndex(row, 2)];
        QColor resColor;

        //文档模式下直接打开颜色对话框获取颜色
        QColorDialog* colorwidget = NEW_AS_QT_CHILD(QColorDialog, m_parent);
        colorwidget->setCurrentColor(qColor);
        resColor = colorwidget->getColor(qColor, m_parent, QString::fromStdWString(GBMP_TR(L"选择颜色")), QColorDialog::ShowAlphaChannel);
        if (resColor.isValid())
        {
            colorButton->setStyleSheet(QString("background-color:%1").arg(resColor.name()));
        }
        else
        {
            colorButton->setStyleSheet(QString("background-color:%1").arg(qColor.name()));
        }
        //删除默认文字
        if (colorButton->text() == STR(L"Default"))
        {
            colorButton->setText(QString::Null());
        }

        m_colorMap[UVIndex(bnt, 2)] = resColor.isValid() ? resColor : qColor;
    }

    void GraphicsStyleTable::OnClickLineTypeCell(int iButtonIndex)
    {
        // 选择线型。
        LineTypeDlg dlg;
        if (dlg.exec() == QDialog::Accepted)
        {
            QString selectLineTypeName = dlg.GetSelectLineTypeName();
            QPushButton* pLineTypeButton = dynamic_cast<QPushButton*>(m_opLineTypeBtnGroup->button(iButtonIndex));
            pLineTypeButton->setText(selectLineTypeName);
        }
    }

    void GraphicsStyleTable::OnApplied()
    {
        if (m_wpUIDoc.Get() == nullptr)
        {
            return;
        }

        gcmp::IDocument* pDoc = m_wpUIDoc->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"doc 为空",L"GDMP",L"2024-03-30");

        if (m_tableType == TableType::ProjectionSectionLines)
        {
            for (int row = 0; row < 9; row++)
            {
                int column = 0;
                //设置投影线宽
                column += 2;
                SetLineWidthCell(row, column);
                column += 2;
                SetColorCell(row, column);
                column += 2;
                SetLineTypeCell(row, column);
                column += 2;
                SetScaleCell(row, column);
                column += 2;
                SetLineWidthCell(row, column);
                column += 2;
                SetColorCell(row, column);
                column += 2;
                SetLineTypeCell(row, column);
                column += 2;
                SetScaleCell(row, column);
                column += 2;
                SetScaleCell(row, column);
                column += 2;
                SetEnabledCell(row, column);
                // 图形节点上样式的名称
                column++;
                m_gOverrideDataList[row]->m_gNodeText = GetTextCell(row, column);
                column++;
                {
                    // 图形节点上样式的类型
                    SetCategoryCell(row, column);
                }
            }
        }
        else if (m_tableType == TableType::ProjectionSectionFaces)
        {
            for (int row = 0; row < 9; row++)
            {
                int column = 0;
                //设置投影线宽
                column += 2;
                SetColorCell(row, column);
                column += 2;
                SetHatchPatternCell(row, column);
                column += 2;
                SetRotateCell(row, column);
                column += 2;
                SetScaleCell(row, column);
                column += 2;
                SetScaleCell(row, column);
                column += 2;
                SetColorCell(row, column);
                column += 2;
                SetHatchPatternCell(row, column);
                column += 2;
                SetRotateCell(row, column);
                column += 2;
                SetScaleCell(row, column);
                column += 2;
                SetColorCell(row, column);
                column += 2;
                SetColorCell(row, column);
            }
        }
    }
#pragma endregion
}

